﻿using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System.DirectoryServices.Protocols;
using System;
using WCS.Entity;
using WcsAip.Models;
using System.Text;
using System.Reflection;
using System.Collections.Generic;
using WcsApi.Controllers;
using WcsApi.Models;
using WCS.Helpers;
using static Google.Protobuf.Reflection.SourceCodeInfo.Types;
using WcsTask.DevCommTaks;
using static WcsAip.Controllers.PDAController;
using WCS.Controls.RunLog;
using System.Linq;
using SqlSugar;
using API.SqlSugar;
using WCS.Entity.SYS;
using WcsTask;

namespace WcsAip.Controllers
{
    [Route("[controller]/[action]")]
    [ApiExplorerSettings(GroupName = "4")]
    [ApiController]
    public class PDAController : Controller
    {
        static SqlSugarDapper _sqlSugarDapper = SqlSugarDapper.GetDbContext();

        static SqlSugarClient _sqlSugarTranDapper = SqlSugarDapper.GetDbTranContext();

        /// <summary>
        /// 托盘替换
        /// </summary>
        /// <param name="pDASendTask"></param>
        /// <returns></returns>
        [HttpPost]
        public Result<object> PalletExchange(PDASendTask pDASendTask)
        {
            try
            {
                // 查询托盘是否在砂芯下线区
                var codequery1 = _sqlSugarDapper.DB.Queryable<LocationInfo>()
                    .Where(l => l.BarCode1 == pDASendTask.oldBarCode && l.StationLocation.Contains("100"))
                    .First();

                var codequery2 = _sqlSugarDapper.DB.Queryable<LocationInfo>()
                   .Where(l => l.BarCode2 == pDASendTask.oldBarCode && l.StationLocation.Contains("100"))
                   .First();

                if (codequery1 == null && codequery2 == null)
                {
                    return Result<object>.error("此旧托盘不在制砂芯下线区，请重新扫描！");
                }

                //要替换的托盘编号
                var barcode = _sqlSugarDapper.DB.Queryable<LocationInfo>()
                    .Where(c => c.BarCode1 == pDASendTask.oldBarCode || c.BarCode2 == pDASendTask.oldBarCode)
                    .First();

                if (barcode == null)
                {
                    return Result<object>.error("旧托盘不存在");
                }

                //修改BarCode1托盘编号
                var codeupdate1 = _sqlSugarDapper.DB.Updateable<LocationInfo>()
                    .SetColumns(p => p.BarCode1 == pDASendTask.newBarCode)
                    .Where(p => p.BarCode1 == pDASendTask.oldBarCode && p.StationLocation.Contains("100"));

                //修改BarCode2托盘编号
                var codeupdate2 = _sqlSugarDapper.DB.Updateable<LocationInfo>()
                   .SetColumns(p => p.BarCode2 == pDASendTask.newBarCode)
                   .Where(p => p.BarCode2 == pDASendTask.oldBarCode && p.StationLocation.Contains("100"));

                var change = pDASendTask.oldBarCode == barcode.BarCode1 ? codeupdate1.ExecuteCommand() : codeupdate2.ExecuteCommand();

                var result = Result<object>.success();
                ApiLogs apiLog = new ApiLogs(
                    $"{MethodBase.GetCurrentMethod().Name}       (PDA扫码替换托盘)",
                    JsonConvert.SerializeObject(pDASendTask),
                    JsonConvert.SerializeObject(result));

                _sqlSugarDapper.DB.Insertable(apiLog).ExecuteCommand();

                return result;
            }
            catch (Exception ex)
            {
                var result = Result<object>.error(ex.Message);
                _sqlSugarDapper.DB.Insertable(new ApiLogs(
                     $"{MethodBase.GetCurrentMethod().Name}       (PDA扫码替换托盘)",
                     JsonConvert.SerializeObject(pDASendTask),
                     JsonConvert.SerializeObject(result))
                 ).ExecuteCommand();

                return Result<object>.error(ex.Message);
            }
        }

        /// <summary>
        /// 铸造叫料
        /// </summary>
        /// <param name="castingSendTask"></param>
        /// <returns></returns>
        [HttpPost]
        public Result<object> CastingMaterials(CastingSendTask castingSendTask)
        {
            try
            {
                var station = _sqlSugarDapper.DB.Queryable<CallMaterial>()
                    .Where(c => c.CallStation == castingSendTask.CallStation)
                    .First();

                var resultree = Result<object>.error("此站台已经呼叫，请勿重复呼叫！");

                CallMaterial callMaterial = new CallMaterial()
                {
                    CallStation = castingSendTask.CallStation,
                };

                if (station == null)
                {
                    _sqlSugarDapper.DB.Insertable(callMaterial).ExecuteCommand();
                }
                else
                {
                    return resultree;
                }

                var result = Result<object>.success();

                ApiLogs apiLog = new ApiLogs(
                    $"{MethodBase.GetCurrentMethod().Name}       (PDA铸造区叫料)",
                    JsonConvert.SerializeObject(castingSendTask),
                    JsonConvert.SerializeObject(result));

                _sqlSugarDapper.DB.Insertable(apiLog).ExecuteCommand();

                return result;
            }
            catch (Exception ex)
            {
                var result = Result<object>.error(ex.Message);
                _sqlSugarDapper.DB.Insertable(new ApiLogs(
                     $"{MethodBase.GetCurrentMethod().Name}       (PDA铸造区叫料)",
                     JsonConvert.SerializeObject(castingSendTask),
                     JsonConvert.SerializeObject(result))
                 ).ExecuteCommand();

                return Result<object>.error(ex.Message);
            }
        }

        /// <summary>
        /// 砂芯下线
        /// </summary>
        /// <param name="callMaterial"></param>
        /// <returns></returns>
        [HttpPost]
        public Result<object> CallMaterial(Calling callMaterial)
        {
            try
            {
                var station = _sqlSugarDapper.DB.Queryable<WcsDevStation>()
                     .Where(w => w.ATTRIBUTE5 == callMaterial.CallStation).First()?.Station_Plc_No;

                if (station == null)
                {
                    return Result<object>.error("站台为空");
                }

                //var codeinfo = _sqlSugarDapper.DB.Queryable<BarCodeInfo>().Where(w => w.isSolve == 0 && w.Station == station).Select(s => s.BarCode).ToList();
                //if (codeinfo.Count < 2)
                //{
                //    return new Result<object> { code = 2, message = $"站台{callMaterial.CallStation}下线砂芯扫描数量不够" };
                //}

                var result = Result<object>.success();
                _sqlSugarTranDapper.BeginTran();
                try
                {
                    //_sqlSugarTranDapper.Updateable<BarCodeInfo>()
                    //    .SetColumns(s => s.isSolve == 1)
                    //    .Where(w => w.isSolve == 0 && w.Station == station && codeinfo.Contains(w.BarCode)).ExecuteCommand();

                    CallMaterial callMaterial1 = new CallMaterial()
                    {
                        CallStation = station,
                        isSupply= callMaterial.isSupply
                    };

                    _sqlSugarDapper.DB.Insertable(callMaterial1).ExecuteCommand();

                    ApiLogs apiLog = new ApiLogs(
                        $"{MethodBase.GetCurrentMethod().Name}       (砂芯下线PDA呼叫)",
                        JsonConvert.SerializeObject(callMaterial),
                        JsonConvert.SerializeObject(result));
                    _sqlSugarDapper.DB.Insertable<ApiLogs>(apiLog).ExecuteCommand();
                    _sqlSugarTranDapper.CommitTran();
                }
                catch (Exception)
                {
                    _sqlSugarTranDapper.RollbackTran();
                }

                return result;
            }
            catch (Exception ex)
            {
                var result = Result<object>.error(ex.Message);
                _sqlSugarDapper.DB.Insertable(new ApiLogs(
                     $"{MethodBase.GetCurrentMethod().Name}       (砂芯下线PDA呼叫)",
                     JsonConvert.SerializeObject(callMaterial),
                     JsonConvert.SerializeObject(result))
                 ).ExecuteCommand();

                return Result<object>.error(ex.Message);
            }
        }

        /// <summary>
        /// 查询物料
        /// </summary>
        /// <param name="trayCode"></param>
        /// <returns></returns>
        [HttpGet]
        public int QueryMaterial(string trayCode)
        {
            try
            {
                string code = trayCode.Substring(6, 8);

                var material = _sqlSugarDapper.DB.Queryable<PalletToMaterial>()
                    .Where(w => w.PalletCode == code)
                    .First();

                var result = Result<object>.success();

                _sqlSugarDapper.DB.Insertable(new ApiLogs(
                    $"{MethodBase.GetCurrentMethod().Name}  获取物料信息",
                    JsonConvert.SerializeObject(material),
                    JsonConvert.SerializeObject("")
                    )).ExecuteCommand();

                return material.ProductId;

            }
            catch (Exception ex)
            {
                _sqlSugarDapper.DB.Insertable(new ApiLogs(
                    $"{MethodBase.GetCurrentMethod().Name}  获取物料信息",
                    JsonConvert.SerializeObject(trayCode),
                    JsonConvert.SerializeObject("")
                    )).ExecuteCommand();

                return 0;
            }
        }

        [HttpPost]
        public Result<object> AGViner(Agv agv)
        {
            try
            {
                _sqlSugarDapper.DB.Updateable<WcsDevStation>()
                    .SetColumns(w => w.ATTRIBUTE3 == agv.ATTRIBUTE3)
                    .SetColumns(w => w.ATTRIBUTE4 == agv.ATTRIBUTE4)
                    .Where(w => w.Station_Plc_No == agv.station)
                    .ExecuteCommand();

                var result = Result<object>.success();

                ApiLogs apiLog = new ApiLogs(
                    $"{MethodBase.GetCurrentMethod().Name}       (AGV到位离开成功)",
                    JsonConvert.SerializeObject(agv),
                    JsonConvert.SerializeObject(result));

                _sqlSugarDapper.DB.Insertable(apiLog).ExecuteCommand();
                return result;
            }
            catch (Exception ex)
            {
                var result = Result<object>.error(ex.Message);
                _sqlSugarDapper.DB.Insertable(new ApiLogs(
                     $"{MethodBase.GetCurrentMethod().Name}       (AGV到位离开失败)",
                     JsonConvert.SerializeObject(agv),
                     JsonConvert.SerializeObject(result))
                 ).ExecuteCommand();

                return Result<object>.error(ex.Message);
            }
        }

        /// <summary>
        /// 手动出库
        /// </summary>
        /// <param name="layer"></param>
        /// <returns></returns>
        [HttpPost]
        public Result<object> OutTask(Layer layer)
        {
            try
            {
                if (layer.layer == "")
                {
                    return Result<object>.error("出库层为空");
                }
                var warehouseCode = layer.layer.Contains("9002") ? "9002" : "9001";
                var l = "";
                if (layer.layer.Length == 6)
                {
                    if (!layer.layer.Contains("9002"))
                    {
                        return Result<object>.error("输入有误");
                    }
                    l = layer.layer.Contains("9002") ? layer.layer.Substring(0, 2) : layer.layer;
                }
                else
                {
                    l = layer.layer.Contains("9002") ? layer.layer.Substring(0, 1) : layer.layer;
                }

                //var warehouseCode = layer.layer.Contains("9002") ? "9002" : "9001";
                //var l = layer.layer.Contains("9002") ? layer.layer.Substring(0, 1) : layer.layer;

                var info1 = _sqlSugarDapper.DB.SqlQueryable<WarehouseInfo>("SELECT *,DATEDIFF(hh, CreateTime,GETDATE()) as dataIff from WCS_WarehouseInfo").Where(w => w.ID == $"{warehouseCode}-{l}" && w.state == (int)StationState.在库).OrderBy(o => o.index).First();
                if (info1 == null)
                {
                    return Result<object>.error("出库层没有可用砂芯");
                }

                mainTask wcsTaskMain = new mainTask
                {
                    Id = Guid.NewGuid().ToString(),
                    Task_Code = ProcessingTaskMain.GenerateRandomCode("main1"),
                    Task_State = 5,
                    Task_Source = 1,
                    Priority = 1,
                    Split = 1,
                    TaskTips = "初始创建",
                    CreateTime = DateTime.Now,
                    Task_Type = "out",
                    TrayBar_Code = info1.barCode,
                    Start_Station = warehouseCode,
                    End_Station = "B001",
                    Current_Station = warehouseCode,
                    StartWMSBinCode = layer.layer.Replace("9002", ""),
                    Replenishment = "4009",
                    MaterialType = "",
                    ProcessType = ProcessType.缓存区到出库口到铸造.ToString(),
                };

                _sqlSugarDapper.DB.Insertable(wcsTaskMain).ExecuteCommand();

                _sqlSugarDapper.DB.Updateable<WarehouseInfo>()
                    .SetColumns(w => w.state == (int)StationState.出库占用)
                    .Where(w => w.barCode == info1.barCode && w.ID == info1.ID && w.index == info1.index)
                    .ExecuteCommand();

                var result = Result<object>.success();

                ApiLogs apiLog = new ApiLogs(
                    $"{MethodBase.GetCurrentMethod().Name}       (出库任务手动创建成功)",
                    JsonConvert.SerializeObject(layer),
                    JsonConvert.SerializeObject(result));

                _sqlSugarDapper.DB.Insertable<ApiLogs>(apiLog).ExecuteCommand();
                return result;
            }
            catch (Exception ex)
            {
                var result = Result<object>.error(ex.Message);
                _sqlSugarDapper.DB.Insertable(new ApiLogs(
                     $"{MethodBase.GetCurrentMethod().Name}       (出库任务手动创建失败)",
                     JsonConvert.SerializeObject(layer),
                     JsonConvert.SerializeObject(result))
                 ).ExecuteCommand();

                return Result<object>.error(ex.Message);
            }
        }

        /// <summary>
        /// 插入barCodeInfo
        /// </summary>
        /// <param name="barCode"></param>
        /// <returns></returns>
        [HttpPost]
        public Result<object> BarCodeInfos(BarCode barCode)
        {
            try
            {
                var station = _sqlSugarDapper.DB.Queryable<WcsDevStation>()
                     .Where(w => w.ATTRIBUTE5 == barCode.Station).First()?.Station_Plc_No;

                if (station == null)
                {
                    return Result<object>.error("站台为空");
                }
                BarCodeInfo barCodeInfo = new BarCodeInfo()
                {
                    BarCode = barCode.barCode,
                    Station = station,
                    isSolve = 0
                };

                _sqlSugarDapper.DB.Insertable(barCodeInfo).ExecuteCommand();

                var result = Result<object>.success();

                _sqlSugarDapper.DB.Insertable(new ApiLogs(
                     $"{MethodBase.GetCurrentMethod().Name}       (上报MES成功,插入barCodeInfo)",
                     JsonConvert.SerializeObject(barCode),
                     JsonConvert.SerializeObject(result))
                 ).ExecuteCommand();

                return result;
            }
            catch (Exception ex)
            {
                var result = Result<object>.error(ex.Message);
                _sqlSugarDapper.DB.Insertable(new ApiLogs(
                     $"{MethodBase.GetCurrentMethod().Name}       (上报MES失败，插入barCodeInfo)",
                     JsonConvert.SerializeObject(barCode),
                     JsonConvert.SerializeObject(result))
                 ).ExecuteCommand();

                return Result<object>.error(ex.Message);
            }
        }

        public class Layer
        {
            public string layer { get; set; }
        }

        public class Agv
        {
            /// <summary>
            /// true
            /// </summary>
            public int ATTRIBUTE3 { get; set; }

            /// <summary>
            /// false
            /// </summary>
            public int ATTRIBUTE4 { get; set; }

            public string station { get; set; }
        }

        public class BarCode
        {
            public string barCode { get; set; }
            public string Station { get; set; }
        }
    }
}
